/*
 * processdetect.cpp
 *
 *  Created on: Feb 11, 2009
 *      Author: yospaly
 */


#include <wx/wx.h>
#include <wx/filename.h>

#include <psapi.h>

static wxString is_locked_by_process(DWORD processID, const wxString& file) {
    HMODULE hMods[1024];
    HANDLE hProcess;
    DWORD cbNeeded;
    unsigned int i;
    
    wxFileName file_fn(file);

    // Print the process identifier.

    // printf( "\nProcess ID: %u\n", processID );

    // Get a list of all the modules in this process.

    hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |
                            PROCESS_VM_READ,
                            FALSE, processID );
    if (NULL == hProcess)
        return wxEmptyString;

    if( EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded))
    {
        for ( i = 0; i < (cbNeeded / sizeof(HMODULE)); i++ )
        {
            TCHAR szModName[MAX_PATH];
            // TCHAR szModLongName[MAX_PATH];

            // Get the full path to the module's file.

            if ( GetModuleFileNameEx(hProcess, hMods[i], szModName, MAX_PATH))
            {
                // Print the module name and handle value.

                // _tprintf( TEXT("\t%s (0x%08X)\n"), szModName, hMods[i] );
            	
            	// GetModuleFileNameEx may return 8.3 dos file path name
            	// GetLongPathName(szModName, szModLongName, MAX_PATH);
            	
        		wxFileName file_fn2(szModName);
        		
            	if ( file_fn.SameAs(file_fn2) ) {
            		// get process name
            		
            		GetModuleFileNameEx(hProcess, NULL, szModName, MAX_PATH);
                	// GetLongPathName(szModName, szModLongName, MAX_PATH);
            		return szModName;
            	}
            }
        }
    }

    CloseHandle( hProcess );
    return wxEmptyString;
}

wxArrayString get_lock_file_processes(const wxString& file) {
    // Get the list of process identifiers.
	
	wxArrayString procs_list;
    DWORD aProcesses[1024], cbNeeded, cProcesses;
    unsigned int i;

    if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) )
        return procs_list;

    // Calculate how many process identifiers were returned.

    cProcesses = cbNeeded / sizeof(DWORD);

    // Print the name of the modules for each process.

    for ( i = 0; i < cProcesses; i++ ) {
    	wxString proc = is_locked_by_process(aProcesses[i], file);
    	if ( !proc.IsEmpty() ) {
            // Get the full path to the module's file.

            procs_list.Add(proc);
    	}
    }
    
    return procs_list;
}
